package com.hamaluik.TradeIn;

import java.util.Iterator;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;

public class TradeInCommandExecutor implements CommandExecutor {
	private final TradeIn plugin;
	private final TradeInItemHandler itemHandler;
	private final TradeInRecipeHandler recipeHandler;
	
	public TradeInCommandExecutor(TradeIn instance) {
		plugin = instance;
		itemHandler = new TradeInItemHandler(instance);
		itemHandler.load();
		recipeHandler = new TradeInRecipeHandler(instance, itemHandler);
		recipeHandler.load();
	}

	@Override
	public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
		// we only care if a player is sending this command
		if(!(sender instanceof Player)) {
			sender.sendMessage("You are not a player!");
			return true;
		}
		
		// aaannnddd grab the player.
		Player player = (Player)sender;

		// check to see what's going on
		if(label.equalsIgnoreCase("trade") && args.length > 0 && plugin.hasPermission(player, "tradein.trade")) {
			// for help, just return usage info
			if(args[0].equalsIgnoreCase("help")) {
				showHelp(player);
				return true;
			}
			else if(args[0].equalsIgnoreCase("list")) {
				if(args.length > 1) {
					// they're searching for a specific recipe
					// look for it..
					if(recipeHandler.recipes.containsKey(args[1])) {
						player.sendMessage(plugin.processColours("&6"+args[1]+"&f:"));
						for(Iterator<ItemStack> it = recipeHandler.recipes.get(args[1]).ingredients.iterator(); it.hasNext();) {
							ItemStack ingredient = (ItemStack)it.next();
							player.sendMessage(plugin.processColours("  &f- &c"+ingredient.getAmount()+" &e"+itemHandler.getItemName(ingredient)));
						}
					}
					else {
						player.sendMessage(plugin.processColours("&cSorry, but that is not a valid trade!"));
					}
				}
				else {
					player.sendMessage(plugin.processColours("&f--- &cAllowed Trades &f---"));
					// hokay, just list all of the recipes they can use
					for(String key: recipeHandler.recipes.keySet()) {
						player.sendMessage(plugin.processColours(" - &6"+key));
					}
				}
				return true;
			}
			else {
				// ok, now check to see if they're trying to do an actual trade!
				if(recipeHandler.recipeExists(args[0])) {
					// get the amount
					Integer amount;
					Integer maxAmount = recipeHandler.maxTrades(args[0], player);
					if(maxAmount < 1) {
						player.sendMessage(plugin.processColours("&cYou do not have the proper items for that trade!"));
						return true;
					}
					if(args.length > 1) {
						if(args[1].equalsIgnoreCase("max") || args[1].equalsIgnoreCase("all")) {
							amount = maxAmount;
						}
						else {
							amount = Integer.parseInt(args[1]);
						}
					}
					else {
						amount = maxAmount;
					}
					// make sure the requested amount is allowed
					if(amount > maxAmount) {
						player.sendMessage(plugin.processColours("&cYou do not have enough for that many trades!"));
						return true;
					}
					
					// ok so we have the proper amount for the trade
					// do the trade!
					PlayerInventory inventory = player.getInventory();
					
					// now take the ingredients away
					// loop through the ingredients
					TradeInRecipe recipe = recipeHandler.recipes.get(args[0]);
					for(Iterator<ItemStack> it = recipe.ingredients.iterator(); it.hasNext();) {
						// grab this item stack
						ItemStack stack = it.next();
						
						// grab the relevant count
						Integer count = itemHandler.countItems(player, stack);
						
						// ok, now remove all those items
						// select for value only if we care!
						if(stack.getDurability() >= 0) {
							ItemStack[] items = inventory.getContents();
							for(int i = 0; i < items.length; i++) {
								if(items[i] != null) {
									if(items[i].getTypeId() == stack.getTypeId() && items[i].getDurability() == stack.getDurability()) {
										inventory.clear(i);
									}
								}
							}
						}
						else {
							inventory.remove(stack.getTypeId());
						}
						
						// and add back the proper amount
						// only if they should have leftovers
						if((count - (amount * stack.getAmount())) > 0) {
							stack.setAmount(count - (amount * stack.getAmount()));
							if(stack.getDurability() < 0) {
								stack.setDurability((short)0);
							}
							inventory.addItem(stack);
						}
					}
					
					// and add the result!
					Integer newId = itemHandler.lookupItem(recipe.result);
					Short newValue = itemHandler.lookupValue(recipe.value);
					// make sure it's a valid value
					if(newValue < 0) {
						newValue = 0;
					}
					ItemStack tradedItems = new ItemStack(newId, recipe.amount * amount, newValue);
					inventory.addItem(tradedItems);
				}
				else {
					// the requested trade did not exist..
					player.sendMessage(plugin.processColours("&cThat trade does not exist!"));
				}
				
				return true;
			}
		}
		
		// show help by default
		showHelp(player);
		return true;
	}
	
	// show formatted help
	// help depends on the permissions of player
	private void showHelp(Player player) {
		if(plugin.hasPermission(player, "tradein.trade")) {
			player.sendMessage(plugin.processColours("&f------------- [&cTradeIn &6Help&f] &f-------------"));
			player.sendMessage(plugin.processColours("&c/trade &6list &e[trade name]"));
			player.sendMessage(plugin.processColours("     &fShow the possible trade-for items"));
			player.sendMessage(plugin.processColours("     &f(Or requirements for a specific trade)"));
			player.sendMessage(plugin.processColours("&c/trade &6<trade name> &e[amount]"));
			player.sendMessage(plugin.processColours("     &fPerforms a trade with optional amount"));
			player.sendMessage(plugin.processColours("     &f(otherwise will trade max. amount possible)"));
			player.sendMessage(plugin.processColours("&c/trade &6help"));
			player.sendMessage(plugin.processColours("     &fShows this help menu"));
		}
		else {
			player.sendMessage(plugin.processColours("&cYou don't have permission to do that!"));
		}
	}
}
